import * as step from '@flow-step/step-toolkit'
import path from 'path';
import * as semver from 'semver'
import process from "process";
import * as util from './util'

const ENV_USE_FOREIGN_CLUSTER: string = 'useForeignCluster'
export const IS_LINUX = process.platform === 'linux';
export const IS_X64 = process.arch === 'x64';
export function checkPythonVersionValid(inputPythonVersion: string): boolean {
    // 检查 inputGOVersion 是否大于等于 2.7，如果不符合则直接抛出异常
    const version = semver.valid(semver.coerce(inputPythonVersion))
    return !(version == null || semver.lt(version, '2.7.0'));
}
export async function installPython(inputPythonVersion: string): Promise<void> {
    if(!IS_LINUX){
        step.error(`Setup Python only supports Linux systems, Please use Linux`)
        process.exit(1);
    }
    if(!IS_X64){
        step.error(`Setup Python only supports X64, Please use X64`)
        process.exit(1);
    }

    let toolName: string = 'python'
    let pythonVersion: string = mapPythonVersion(inputPythonVersion)
    if (!checkPythonVersionValid(pythonVersion)) {
        throw new Error(`The input version ${pythonVersion} is not supported, please use version >= 2.7`)
    }
    step.info(`Going to install the python with version ${pythonVersion}`)
    try {
        let platform: string = step.platform.getPlatform()
        let toolSuffix = getToolSuffix(platform)

        const pythonCachedPath = await step.tool.install(toolName, pythonVersion, toolSuffix)

        await setupPython(pythonCachedPath,pythonVersion,inputPythonVersion)
    } catch (err) {
        throw new Error(`Install Python ${pythonVersion} failed, ${err}`)
    }

    step.info(`Install Python ${pythonVersion} -> ${pythonVersion} successfully!`)
}

export async  function setupPython(pythonCachedPath: string,pythonVersion : string, inputPythonVersion: string) : Promise<void>{
    step.info(`PythonPath: ${pythonCachedPath}`)

    const currentPath = process.cwd()
    step.info("TOOLCACHE_ROOT "+currentPath)
    step.exportEnvVar('TOOLCACHE_ROOT', currentPath);
    util.changeDirectory(pythonCachedPath)

    await util.executeCmdSync('bash', ['./setup.sh']);
    const installDir= `${currentPath}${util.SEP}Python${util.SEP}${pythonVersion}${util.SEP}`;
    const pythonPath = path.join(installDir)
    step.info(pythonPath)
    step.addPath(pythonPath)
    const pythonBinPath = path.join(`${installDir}${util.SEP}bin`)

    step.addPath(pythonBinPath)
    // 建立软链

    await util.createSymlink(`${pythonBinPath}${util.SEP}pip3`,`${pythonBinPath}${util.SEP}pip`,`${pythonBinPath}${util.SEP}`);
    await util.createSymlink(`${pythonBinPath}${util.SEP}python`,`/opt/hostedtoolcache/Python/${pythonVersion}/x64/bin/python${inputPythonVersion}`,`/opt/hostedtoolcache/Python/${pythonVersion}/x64/bin`);

    const pyLibPath = path.join(installDir, 'lib');

    const ldDibPath = process.env['LD_LIBRARY_PATH']
        ?  process.env['LD_LIBRARY_PATH']
        : '';
    if (!ldDibPath.split(':').includes(pyLibPath)) {
        step.exportEnvVar('LD_LIBRARY_PATH', pyLibPath + ldDibPath);
    }
    await util.executeCmdSync('python', ['--version']);
}

export function getToolSuffix(platform: string): string {
    return platform === step.platform.PLATFORM_WIN ? "zip" : "tar.gz";
}

export function mapPythonVersion(pythonVersion: string): string {
    switch (pythonVersion) {
        case '2.7':
            return '2.7.13'
        case '3.5':
            return '3.5.4'
        case '3.6':
            return '3.6.7'
        case '3.7':
            return '3.7.5'
        case '3.8':
            return '3.8.5'
        case '3.9':
            return '3.9.5'
        case '3.10':
            return '3.10.5'
        case '3.11':
            return '3.11.5'
        case '3.12':
            return '3.12.3'
        default:
            return pythonVersion
    }
}